﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bank
{
    /// <summary>
    /// Класс "Банковский счёт"
    /// </summary>
    class Account
    {
		protected static int Count = 0; // Счётчик счетов
		protected Client _owner;		// клиент к которому относится счет
		protected Bank _bank;
		protected double _balance;		// Баланс счёта (сумма денег на счёте)
		protected string _id;			// ID счёта (номер счёта)
		protected DateTime _startDate;	// Дата открытия счёта
		protected DateTime _expireDate;	// Дата закрытия счёта

		/// <summary>
		/// свойство "Дата создания счёта"
		/// </summary>
		public DateTime StartDate
		{
			get
			{
				return _startDate;
			}
		}

		/// <summary>
		/// Владелец счёта
		/// </summary>
		public Client ClientOwner
		{
			get 
			{ 
				return this._owner; 
			}
		}

		/// <summary>
		/// Банк-владелец счёта
		/// </summary>
		public Bank BankOwner
		{
			get
			{
				return this._bank;
			}
		}

		/// <summary>
		/// Дата закрытия счёта
		/// </summary>
		public DateTime ExpireDate
		{
			get
			{
				return _expireDate;
			}
		}

		/// <summary>
		/// Изменение баланса счёта
		/// </summary>
		public double Balance
		{
			get { return this._balance; }
			set 
			{ 
				// Если значение отрицательное - выходим
				if (value < 0) 
					throw new ArgumentException("Изменить баланс счёта "+ this.ID + " не удалось"); 
				_balance = value; 
			}
		}

		/// <summary>
		/// ID счёта
		/// </summary>
		public string ID
		{
			get { return _id; }
		}

		/// <summary>
		/// Генератор номера счёта в формате XXX-XXXXXX-YY-MM {XXX - номер банка; XXXXXX - счётчик; YY-год; MM - месяц}
		/// </summary>
		/// <returns>ID счёта</returns>
		public string GenerateID()
		{
			string formatStringBank = "D3";
			string formatString = "D6";
			string formatDate = "yy-MM";
			// получим текущую дату
			DateTime currDate = DateTime.Now;
			// увеличим счётчик счетов
			Count++;
			// сгенерируем номер счёта в формате XXX-XXXXXX-YY-MM
			string tmpID = BankOwner.ID.ToString(formatStringBank) + "-" + Count.ToString(formatString) + "-" + currDate.ToString(formatDate);
			return tmpID;
		}

		/// <summary>
		/// Положить деньги на счёт
		/// </summary>
		/// <param name="amount">Сумма</param>
		/// <returns>bool</returns>
		public bool MoneyInc(double amount)
		{
			this.Balance += amount;
			this.Message("Деньги успешно зачислены на счёт "+ this.ID);
			return true;
		}

		/// <summary>
		/// Снять деньги со счёта
		/// </summary>
		/// <param name="amount">Сумма</param>
		/// <returns></returns>
		public bool MoneyDec(double amount)
		{
			// Если сумма денег <= баланса
			if (amount <= this._balance)
			{
				this.Balance -= amount;
				this.Message("Деньги успешно сняты со счёта " + this.ID);
				return true;
			}
			else // снятие невозможно
			{
				this.Message("На счёте " + this.ID + " лежит сумма меньше, чем запрашиваемая");
				return false;
			}
		}

		/// <summary>
		/// Вывести информацию о счёте
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			StringBuilder message = new StringBuilder();
			message.Append("Банк в котором открыт счёт: " + BankOwner.Name + "\n");
			message.Append("№ счёта: " + this.ID + "\n");

			// Если клиент - физлицо
			if (ClientOwner.Information.clType == ClientType.Phisical)
			{
				message.Append("Владелец счёта: " + ClientOwner.Information.FistName + " " + ClientOwner.Information.LastName + "\n");
				message.Append("Дата открытия счёта: " + this.StartDate + "\n");
				message.Append("Дата закрытия счёта: " + this.ExpireDate + "\n");
				message.Append("Дата рождения клиента: " + ClientOwner.Information.dob + "\n");
				message.Append("Адрес клиента: " + ClientOwner.Information.Address + "\n");
				message.Append("Серия и номер паспорта: " + ClientOwner.Information.PassportNumber + "\n");
			}
			else // Если клиент - юрлицо
			{
				message.Append("Владелец счёта: " + ClientOwner.Information.OrgName + "\n");
				message.Append("Дата открытия счёта: " + this.StartDate + "\n");
				message.Append("Дата закрытия счёта: " + this.ExpireDate + "\n");
				message.Append("Адрес юр.лица: " + ClientOwner.Information.Address + "\n");
			}
			message.Append("Текущий баланс на счёте: " + this.Balance + "\n");
			// Выведем информацию на консоль
			this.Message(message.ToString());
			return message.ToString();
			//return base.ToString();
		}

		/// <summary>
		/// Конструктор
		/// </summary>
		/// <param name="bank">Банк-владелец</param>
		/// <param name="client">Клиент-владелец</param>
		/// <param name="DateExpire">Дата закрытия счёта</param>
		/// <param name="initBalance">Сумма денег на счёте</param>
		public Account(Bank bank, Client client, DateTime DateExpire, double initBalance=0)
		{
			Balance = initBalance;
			_bank = bank;			
			_owner = client;
			_startDate = DateTime.Now;
			_expireDate = DateExpire;
			_id = this.GenerateID();
		}

		/// <summary>
		/// Вывести сообщение в консоль
		/// </summary>
		/// <param name="msg"></param>
		void Message(string msg)
		{
			Console.WriteLine(msg);
		}
    }
}
